資料快取是將一些 PHP 變數儲存在快取中,並在稍後從快取中檢索出來。它也是更進階快取功能的基礎,例如 查詢快取 和 頁面快取。
以下程式碼是資料快取的典型用法模式,其中 $cache
指的是 快取組件
// try retrieving $data from cache
$data = $cache->get($key);
if ($data === false) {
// $data is not found in cache, calculate it from scratch
$data = $this->calculateSomething();
// store $data in cache so that it can be retrieved next time
$cache->set($key, $data);
}
// $data is available here
自 2.0.11 版本起,快取組件 提供了 getOrSet() 方法,簡化了資料取得、計算和儲存的程式碼。以下程式碼與先前的範例執行完全相同的操作
$data = $cache->getOrSet($key, function () {
return $this->calculateSomething();
});
當快取具有與 $key
相關聯的資料時,將傳回快取的值。否則,將執行傳遞的匿名函式以計算將被快取並傳回的值。
如果匿名函式需要來自外部作用域的一些資料,您可以使用 use
語句傳遞它。例如
$user_id = 42;
$data = $cache->getOrSet($key, function () use ($user_id) {
return $this->calculateSomething($user_id);
});
注意: getOrSet() 方法也支援持續時間和依賴性。請參閱 快取過期 和 快取依賴 以了解更多資訊。
資料快取依賴於所謂的快取組件,這些組件代表各種快取儲存,例如記憶體、檔案、資料庫。
快取組件通常註冊為 應用程式組件,以便它們可以全局配置和存取。以下程式碼顯示如何配置 cache
應用程式組件以使用 memcached 與兩個快取伺服器
'components' => [
'cache' => [
'class' => 'yii\caching\MemCache',
'servers' => [
[
'host' => 'server1',
'port' => 11211,
'weight' => 100,
],
[
'host' => 'server2',
'port' => 11211,
'weight' => 50,
],
],
],
],
然後,您可以使用表達式 Yii::$app->cache
存取上述快取組件。
如果未指定快取組件,則 Yii 將使用 yii\caching\FileCache 作為預設值。
由於所有快取組件都支援相同的 API 集,您可以通過在應用程式配置中重新配置它,來將底層快取組件與不同的組件交換,而無需修改使用快取的程式碼。例如,您可以修改上述配置以使用 APC 快取
'components' => [
'cache' => [
'class' => 'yii\caching\ApcCache',
],
],
提示: 您可以註冊多個快取應用程式組件。名為
cache
的組件預設由許多依賴快取的類別(例如 yii\web\UrlManager)使用。
Yii 支援廣泛的快取儲存。以下是摘要
false
來停用儲存資料的序列化。Yii::$app->cache->get($key)
來嘗試從快取中檢索資料,而無需擔心 Yii::$app->cache
可能為 null
。提示: 您可以在同一個應用程式中使用不同的快取儲存。常見的策略是使用基於記憶體的快取儲存來儲存小但經常使用的資料(例如,統計資料),並使用基於檔案或資料庫的快取儲存來儲存大且不經常使用的資料(例如,頁面內容)。
所有快取組件都具有相同的基類 yii\caching\Cache,因此支援以下 API
false
值。注意: 不要直接快取
false
布林值,因為 get() 方法使用false
傳回值來指示在快取中找不到資料項目。您可以將false
放在陣列中,並快取此陣列以避免此問題。
某些快取儲存(例如 MemCache、APC)支援以批次模式檢索多個快取值,這可以減少檢索快取資料所涉及的開銷。提供了 API multiGet() 和 multiAdd() 以利用此功能。如果底層快取儲存不支援此功能,則將模擬它。
由於 yii\caching\Cache 實作了 ArrayAccess
,因此快取組件可以像陣列一樣使用。以下是一些範例
$cache['var1'] = $value1; // equivalent to: $cache->set('var1', $value1);
$value2 = $cache['var2']; // equivalent to: $value2 = $cache->get('var2');
儲存在快取中的每個資料項目都由一個鍵唯一標識。當您在快取中儲存資料項目時,您必須為其指定一個鍵。稍後,當您從快取中檢索資料項目時,您應該提供相應的鍵。
您可以使用字串或任意值作為快取鍵。當鍵不是字串時,它將自動序列化為字串。
定義快取鍵的常見策略是將所有決定因素包含在陣列中。例如,yii\db\Schema 使用以下鍵來快取關於資料庫表的結構描述資訊
[
__CLASS__, // schema class name
$this->db->dsn, // DB connection data source name
$this->db->username, // DB connection login user
$name, // table name
];
如您所見,該鍵包含唯一指定資料庫表所需的所有必要資訊。
注意: 通過 multiSet() 或 multiAdd() 儲存在快取中的值只能具有字串或整數鍵。如果您需要設定更複雜的鍵,請通過 set() 或 add() 單獨儲存該值。
當不同的應用程式使用相同的快取儲存時,您應該為每個應用程式指定唯一的快取鍵前綴,以避免快取鍵衝突。這可以通過配置 yii\caching\Cache::$keyPrefix 屬性來完成。例如,在應用程式配置中,您可以編寫以下程式碼
'components' => [
'cache' => [
'class' => 'yii\caching\ApcCache',
'keyPrefix' => 'myapp', // a unique cache key prefix
],
],
為了確保互操作性,應僅使用字母數字字元。
儲存在快取中的資料項目將永遠保留在那裡,除非由於某些快取策略強制執行(例如,快取空間已滿且最舊的資料被移除)而被移除。要更改此行為,您可以在調用 set() 以儲存資料項目時提供過期參數。該參數指示資料項目可以在快取中保持有效的秒數。當您調用 get() 來檢索資料項目時,如果它已超過過期時間,則該方法將傳回 false
,指示在快取中找不到資料項目。例如,
// keep the data in cache for at most 45 seconds
$cache->set($key, $data, 45);
sleep(50);
$data = $cache->get($key);
if ($data === false) {
// $data is expired or is not found in the cache
}
自 2.0.11 版本起,如果您希望自訂快取持續時間而不是預設的無限持續時間,您可以在快取組件配置中設定 defaultDuration 值。這將允許您不必每次都將自訂 duration
參數傳遞給 set()。
除了過期設定外,快取資料項目也可能因所謂的快取依賴的更改而失效。例如,yii\caching\FileDependency 表示檔案修改時間的依賴性。當此依賴性更改時,表示相應的檔案已修改。因此,應使在快取中找到的任何過時的檔案內容失效,並且 get() 調用應傳回 false
。
快取依賴表示為 yii\caching\Dependency 後代類別的物件。當您調用 set() 以在快取中儲存資料項目時,您可以傳遞關聯的快取依賴物件。例如,
// Create a dependency on the modification time of file example.txt.
$dependency = new \yii\caching\FileDependency(['fileName' => 'example.txt']);
// The data will expire in 30 seconds.
// It may also be invalidated earlier if example.txt is modified.
$cache->set($key, $data, 30, $dependency);
// The cache will check if the data has expired.
// It will also check if the associated dependency was changed.
// It will return false if any of these conditions are met.
$data = $cache->get($key);
以下是可用快取依賴的摘要
注意: 避免將 exists() 方法與依賴項一起使用。它不檢查與快取資料關聯的依賴項(如果有的話)是否已更改。因此,調用 get() 可能會傳回
false
,而 exists() 傳回true
。
查詢快取是建立在資料快取之上的特殊快取功能。它旨在快取資料庫查詢的結果。
查詢快取需要 資料庫連線 和有效的 cache
應用程式組件。查詢快取的基本用法如下,假設 $db
是 yii\db\Connection 實例
$result = $db->cache(function ($db) {
// the result of the SQL query will be served from the cache
// if query caching is enabled and the query result is found in the cache
return $db->createCommand('SELECT * FROM customer WHERE id=1')->queryOne();
});
查詢快取可用於 DAO 以及 ActiveRecord
$result = Customer::getDb()->cache(function ($db) {
return Customer::find()->where(['id' => 1])->one();
});
資訊: 某些 DBMS(例如 MySQL)也支援 DB 伺服器端的查詢快取。您可以選擇使用任一查詢快取機制。上面描述的查詢快取的優勢在於,您可以指定彈性的快取依賴性,並且可能更有效率。
自 2.0.14 版本起,您可以使用以下快捷方式
(new Query())->cache(7200)->all();
// and
User::find()->cache(7200)->all();
查詢快取通過 yii\db\Connection 具有三個全局可配置選項
true
。請注意,要有效地開啟查詢快取,您還需要具有有效的快取,如 queryCache 所指定。'cache'
。僅當存在有效的快取應用程式組件時,才啟用查詢快取。如果您有多個需要利用查詢快取的 SQL 查詢,則可以使用 yii\db\Connection::cache()。用法如下:
$duration = 60; // cache query results for 60 seconds.
$dependency = ...; // optional dependency
$result = $db->cache(function ($db) {
// ... perform SQL queries here ...
return $result;
}, $duration, $dependency);
匿名函式中的任何 SQL 查詢都將以指定的依賴性快取指定的持續時間。如果在快取中找到有效的查詢結果,則將跳過查詢,並且結果將改為從快取中提供。如果您未指定 $duration
參數,則將改為使用 queryCacheDuration 的值。
有時在 cache()
中,您可能想要對某些特定查詢停用查詢快取。在這種情況下,您可以使用 yii\db\Connection::noCache()。
$result = $db->cache(function ($db) {
// SQL queries that use query caching
$db->noCache(function ($db) {
// SQL queries that do not use query caching
});
// ...
return $result;
});
如果您只想對單個查詢使用查詢快取,則可以在建構命令時調用 yii\db\Command::cache()。例如,
// use query caching and set query cache duration to be 60 seconds
$customer = $db->createCommand('SELECT * FROM customer WHERE id=1')->cache(60)->queryOne();
您也可以使用 yii\db\Command::noCache() 來停用單個命令的查詢快取。例如,
$result = $db->cache(function ($db) {
// SQL queries that use query caching
// do not use query caching for this command
$customer = $db->createCommand('SELECT * FROM customer WHERE id=1')->noCache()->queryOne();
// ...
return $result;
});
查詢快取不適用於包含資源處理程式的查詢結果。例如,當在某些 DBMS 中使用 BLOB
欄位類型時,查詢結果將傳回欄位資料的資源處理程式。
某些快取儲存具有大小限制。例如,memcache 將每個條目的最大大小限制為 1MB。因此,如果查詢結果的大小超過此限制,則快取將失敗。
當您需要使所有儲存的快取資料失效時,可以調用 yii\caching\Cache::flush()。
您也可以通過調用 yii cache/flush
從主控台刷新快取。
yii cache
:列出應用程式中可用的快取yii cache/flush cache1 cache2
:刷新快取組件 cache1
、cache2
(您可以傳遞多個組件名稱,以空格分隔)yii cache/flush-all
:刷新應用程式中的所有快取組件yii cache/flush-schema db
:清除給定連線組件的 DB 結構描述快取資訊: 主控台應用程式預設使用單獨的配置文件。確保您的 Web 和主控台應用程式配置中具有相同的快取組件,以達到適當的效果。
發現錯字或您認為此頁面需要改進?
在 github 上編輯它 !
如果使用
where
子句,這會壞掉
User::find()->where(['id' => $id])cache(7200)->all();
將傳回原始快取結果,無論 ID 是否已更改。可能的解決方案是 1,使用 where 子句作為快取的雜湊,或 2 允許在快取持續時間之外指定快取 ID。
註冊 或 登入 以發表評論。